﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace CloudReader.Net.Server
{
    /// <summary>
    /// 管理连接
    /// </summary>
    public class Connection
    {
        /// <summary>
        /// 对象的上下文集合，用于处理上下文的唯一性
        /// </summary>
        public static HashSet<string> ConnectionContextPool = new HashSet<string>();
        public static int Frame = 4096;//定义数据帧


        public Connection()//用一个接收的套接字初始化连接
        {
            //每个接收的套接字都对应一个读写SAEA
            m_buffer = new byte[Connection.Frame];
            ReadEventArgs = new SocketAsyncEventArgs();
            WriteEventArgs = new SocketAsyncEventArgs();
            ReadEventArgs.SetBuffer(m_buffer, 0, Connection.Frame);
            Context = GetContext();
            Buffer = new DynamicBuffer();
            Buffer.RecieveCompleted += (obj) =>
            {
                OnReceiveCompleted(this.ReadEventArgs, obj);
            };
            isLogin = false; 
        }

        string GetContext()
        {
            var data = new byte[4];
            var rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(data);
            var seed = BitConverter.ToInt32(data, 0);
            Random r = new Random(seed);
            var str = "0123456789abcdefgijklmnopqrstuvwxyz+=/@$%^&";
            var sb = new StringBuilder();
            for (int i = 0; i < 32; i++)
            {
                sb.Append(str[r.Next(0, str.Length - 1)]);
            }
            var s = sb.ToString();
            try
            {
                Connection.ConnectionContextPool.Add(s);
            }
            catch
            {
                s = GetContext();
            }
            return s;
        }

        public DateTime ConnectedTime { get; set; }

        public event Action<SocketAsyncEventArgs, Protocol.CloudReaderPackage> OnReceiveCompleted;
        public SocketAsyncEventArgs ReadEventArgs { get; set; }
        public DateTime ActiveTime { get; set; }

        public SocketAsyncEventArgs WriteEventArgs { get; set; }

        public bool isLogin { get; set; }
        public Socket Connect;
        public string Context { get; set; }
        public string Uid { get; set; }
        byte[] m_buffer { get; set; }
        public DynamicBuffer Buffer { get; set; }

        public void SetUid(string uid)
        {
            if (string.IsNullOrEmpty(Uid))
            {
                Uid = uid;
            }
            else
            {
                throw new Exception("已经赋值过了");
            }
        }
        public void SetSocket(Socket s)
        {
            Connect = s;
            //链式赋值，将接收到的套接字作为用户对象传递
            ReadEventArgs.UserToken = WriteEventArgs.UserToken = this;
        }


        public void Close()
        {
            Connect.Close();
            ReadEventArgs.UserToken = null;
            WriteEventArgs.UserToken = null;
            ConnectionContextPool.Remove(this.Context);
            Uid = "";
            isLogin = false;
        }
    }
}
